import { ref } from 'vue'
import axios from 'axios';
import { RestaurantItem, IVoiceActor, VoiceActor, IVoiceTag, IVoiceCat, IVoiceStyle, Speech, VoiceStyle, VoiceRoleArgs, ISpeech,GetBaseURL } from '../../../../composables/types';
import { el, tr } from 'element-plus/es/locale';

// 定义接口描述 JSON 对象的结构
interface SubtitleSegment {
  text: string;
  startTime: number;
  endTime: number;
}

  // 定义接口描述分割后的文本段落
export interface TextSegment {
  text: string;
  startIndex: number;
  endIndex: number;
}
// 定义接口描述分割后的文本段落
export interface Audioreturn {
  duration: number;
  audioUrl: string;
  code: number;
  message: string;

}

// 定义接口描述分割后的音频段落
interface SegmentInfo {
  //下标
  index: number;
  //文本内容
  text: string;
  //时长
  duration: number;
  //音频地址
  audioUrl: string;
}

///将一个长的小说分割为几个小段方便生成配音
export function useAudio() {
  const audioUrl2 = ref('sunsun')


  /**
   * 分割字幕
   * @param text 文本
   * @returns 返回一个TextSegment数组
   */
  function Subtitlesegmentation(text: any): TextSegment[] {  // 返回类型为 SubtitleSegment 数组
    const pureText = text.replace(/[\r\n]+/g, '');
    const punctuations = '。！？，；：、';
    const minLength = 20;
    let segments: TextSegment[] = [];
    let currentSegment = '';
    let startIndex = 0;

    for (let i = 0; i < pureText.length; i++) {
      currentSegment += pureText[i];

      if (punctuations.includes(pureText[i]) && currentSegment.length >= minLength) {
        segments.push({
          text: currentSegment,
          startIndex: startIndex,
          endIndex: i
        });
        currentSegment = '';
        startIndex = i + 1;
      }
    }

    // 处理最后一个段落
    if (currentSegment.length > 0) {
      segments.push({
        text: currentSegment,
        startIndex: startIndex,
        endIndex: text.length - 1
      });
    }

    return segments;
  }


  // 其他音频相关的方法...

  return {
    audioUrl2,
    Subtitlesegmentation,
    // 返回其他需要在组件中使用的变量和方法
  }
}

/**
 * 获取音频时长
 * @param url 音频URL
 * @returns 返回一个Promise，解析为音频时长（秒）
 */
export function getAudioDuration(url: string): Promise<number> {


  return new Promise((resolve, reject) => {
    try {
      const audio = new Audio(url);

      audio.addEventListener('loadedmetadata', () => {

        // 音频元数据加载完成后，可以获取持续时间
        resolve(audio.duration);
      });

      audio.addEventListener('error', (event) => {
        // 加载出错时拒绝 Promise
        reject(new Error('音频加载失败'));
      });

      // 开始加载音频
      audio.load();
    } catch (error) {
      resolve(0);
    }

  });
}



/**
 * 格式化时间（秒）为 mm:ss 格式
 * @param seconds 秒数
 * @returns 格式化后的时间字符串
 */
export function formatDuration(seconds: number): string {
  const minutes = Math.floor(seconds / 60);
  const remainingSeconds = Math.floor(seconds % 60);
  return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
}


//文本转语音返回URL
/**
 * 将文本转换为语音的异步函数
 * @param speechArgs 包含语音合成所需参数的对象
 * @returns 返回一个Promise，解析为音频URL字符串
 * @获取一个时长 返回一个Promise，解析为音频URL字符串
 * 
 * 此函数使用axios向指定的API端点发送POST请求，以将给定的文本转换为语音
 * 它封装了文本、发音人、语速、音量、音调、讲话风格、角色扮演、风格强度和停顿时间等参数
 * 在成功接收到响应后，它从响应数据中提取音频URL并返回该URL
 * 如果发生错误，它会将错误打印到控制台并抛出错误
 */
export async function textToSpeech(speechArgs: Speech): Promise<Audioreturn> {
  console.log('开始处理文本:', speechArgs.text);
  const baseUrl: string = GetBaseURL();
  const formData = new FormData();

  Object.entries(speechArgs).forEach(([key, value]) => {
    formData.append(key, value.toString());
  });

  const axiosConfig = {
    headers: {
      'Content-Type': 'multipart/form-data; boundary=---011000010111000001101001',
      'App-Secret': 'a215dc346000ee4e699cbdedb96470fc',
    },
  };

  const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
  const baseDelay = 1000;
  let retryCount = 0;
  const maxRetries = 3;

  while (retryCount < maxRetries) {
    try {
      console.log(`尝试生成音频 (${retryCount + 1}/${maxRetries})`);
      const response = await axios.post(`${baseUrl}/api/tts/tts/textToSpeech_url`, formData, axiosConfig);
      const audioUrl = response.data.url;

      if (audioUrl) {
        console.log('获取到音频 URL:', audioUrl);
        try {
          const duration = await getAudioDuration(audioUrl);
          console.log('音频时长:', duration);
          
          if (duration > 0) {
            return { duration, audioUrl,code:200,message:"生成成功" };
          } else {
            console.warn('音频时长无效，将重试');
          }
        } catch (error) {
          console.error('获取音频时长错误:', error);
        }
      } else {
        console.warn('未获取到有效的音频 URL，将重试');
      }
    } catch (error) {
      if (axios.isAxiosError(error)) {
        console.error('网络错误:', error.message);
      } else {
        console.error('未知错误:', error);
      }
    }

    retryCount++;
    const delayTime = baseDelay * Math.pow(2, retryCount);
    console.log(`等待 ${delayTime}ms 后重试`);
    await delay(delayTime);
  }
  return { duration: 0, audioUrl: '', code: 500, message: "达到最大重试次数，无法生成有效的音频" };
}


///使用ffmpeg将视频合并合并音频
export async function mergedAudio(segmentData: SegmentInfo[]): Promise<string> {
  try {
    console.log('合并:', segmentData);

    // 构建请求体
    const requestBody = JSON.stringify(segmentData);

    // 发送请求到后端
    const backendUrl = 'https://your-backend-url.com/merge-audio'; // 替换为你的后端URL
    const response = await fetch(backendUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: requestBody
    });

    if (!response.ok) {
      throw new Error(`Backend returned an error: ${response.status} ${response.statusText}`);
    }

    const mergedAudioUrl = await response.text(); // 假设后端返回合并后的音频URL
    return mergedAudioUrl;

  } catch (error) {
    console.error('合并音频错误:', error);
    return "";
  }
}
/**
 * 将文本转换为语音的异步函数（流式数据返回）
 * @param speechArgs 包含语音合成所需参数的对象
 * @returns 返回一个Promise，解析为音频URL字符串
 * 
 * 此函数使用axios向指定的API端点发送POST请求，以将给定的文本转换为语音
 * 它封装了文本、发音人、语速、音量、音调、讲话风格、角色扮演、风格强度和停顿时间等参数
 * 在成功接收到响应后，它从响应数据中创建一个Blob对象，并生成一个URL，然后返回该URL
 * 如果API返回的音频URL为空或无效，函数会继续重试直到获取有效的URL
 * 如果发生错误，它会将错误打印到控制台并抛出错误
 */
export async function textToSpeechBlob(speechArgs: Speech): Promise<string> {
  // 接口地址
  const baseUrl: string = GetBaseURL();
  const formData = new FormData();
  let audioUrl: string = "";

  // 以下代码行将speechArgs中的各个属性添加到formData中，以便后续的API请求使用
  formData.append('text', speechArgs.text);  // 语音的文本
  formData.append('voiceName', speechArgs.voiceName); // 发音人 zh-CN-YunxiNeural
  formData.append('rate', speechArgs.rate);  // 语速 '1.0'
  formData.append('volume', speechArgs.volume);  // 音量 '+10.00%'
  formData.append('pitch', speechArgs.pitch);  // 音调 '+10.00%'
  formData.append('style', speechArgs.style);  // 讲话风格 'cheerful'，可以表达快乐、同情和平静等情绪。 也可以针对不同场景（例如客户服务、新闻广播和语音助理）优化语音。
  formData.append('role', speechArgs.role);  // 讲话角色扮演 ''，声音可以模仿不同的年龄和性别，但声音名称不会更改，男性语音可以提高音调和改变
  formData.append('styleDegree', speechArgs.styleDegree);  // 讲话风格的强度 ''，可以指定更强或更柔和的风格，使语音更具表现力或更柔和， 可接受值的范围为：0.01 到 2（含），默认值为 1，表示预定义的风格强度，最小单位为 0.01，表示略倾向于目标风格，值为 2 表示是默认风格强度的两倍。
  formData.append('breakTime', speechArgs.breakTime);  // 停顿时间 '250'

  try {
    // 发送POST请求到API，包括封装好的formData和必要的请求头

    const response = await axios.post(
      `${baseUrl}/api/tts/tts/textToSpeech`,
      formData,
      {
        headers: {
          'Content-Type': 'multipart/form-data; boundary=---011000010111000001101001',
          'App-Secret': 'a215dc346000ee4e699cbdedb96470fc',
        },
        responseType: 'arraybuffer', // 设置响应类型为 arraybuffer
      }
    );

    // 从API响应数据中创建Blob对象，并生成URL
    const blob = new Blob([response.data], { type: 'audio/mpeg' });
    audioUrl = URL.createObjectURL(blob);
    console.log('音频 URL:', audioUrl);


    // 返回音频URL
    return audioUrl;
  } catch (error) {
    // 捕获到错误时，将其打印到控制台并抛出错误
    console.error('Error错误捕捉:', error);
    throw error;
  }
}